using System;
using System.Collections.Generic;
using System.Text;
using Directory.Model;
using System.Data;

namespace Directory.BLL
{
	public class Category
	{
		private static Directory.IDAL.ICategory dal = new Directory.DAL.Category();

		public CategoryInfo CreateCategory(string categoryName, int parentCategoryId, string description, string marker, int order, out CategoryInfo.ErrorCode ErrorCode)
		{
			if (BLLHelper.ValidateNotEmptyStringParameter(ref categoryName))
			{
				return dal.CreateCategory(categoryName, parentCategoryId, description, marker, order, out ErrorCode);
			}
			else
			{
				ErrorCode = CategoryInfo.ErrorCode.InvalidName;
				return null;
			}
		}

		public bool TryDeleteCategory(int categoryId)
		{
			CategoryInfo.ErrorCode code;
			dal.DeleteCategory(categoryId, out code);
			return (code == CategoryInfo.ErrorCode.Success);
		}

		public void UpdateCategory(CategoryInfo category, out CategoryInfo.ErrorCode ErrorCode)
		{
			string categoryName = category.CategoryName;
			if (BLLHelper.ValidateNotEmptyStringParameter(ref categoryName))
			{
				category.CategoryName = categoryName;
				dal.UpdateCategory(category, out ErrorCode);
			}
			else
			{
				ErrorCode = CategoryInfo.ErrorCode.InvalidName;
			}
		}

		public IList<CategoryInfo> GetChildsOfCategory(int categoryId)
		{
			return dal.GetChildsOfCategory(categoryId);
		}

		public IList<CategoryInfo> GetRootCategoriesForUser(string username)
		{
			if (BLLHelper.ValidateNotEmptyStringParameter(ref username))
			{
				return dal.GetRootCategoriesForUser(username);
			}
			else
			{
				return null;
			}
		}

		public IList<CategoryUser> GetUsersForCategory(int categoryId, int pageIndex, int pageSize, out int totalRecords)
		{
			return dal.GetUsersForCategory(categoryId, pageIndex, pageSize, out totalRecords);
		}

		public void AddUserToCategory(string username, int categoryId)
		{
			if (BLLHelper.ValidateUserName(ref username))
			{
				dal.AddUserToCategory(username, categoryId);
			}
			else
			{
				throw new ArgumentException("Invalid username parameter.");
			}
		}

		public void RemoveUserFromCategory(string username, int categoryId)
		{
			if (BLLHelper.ValidateUserName(ref username))
			{
				dal.RemoveUserFromCategory(username, categoryId);
			}
			else
			{
				throw new ArgumentException("Invalid username parameter.");
			}
		}

		public CategoryInfo GetCategoryInfo(int categoryId)
		{
			return dal.GetCateogryInfo(categoryId);
		}

		public IList<CategoryInfo> GetRecursiveChildCategoriesForUser(string username)
		{
			if (BLLHelper.ValidateUserName(ref username))
			{
				IList<CategoryInfo> rawList = dal.GetRecursiveChildCategoriesForUser(username);
				TydyCategoryList(rawList);
				return rawList;
			}
			else
			{
				//throw new ArgumentException("Invalid username parameter.");
				return null;
			}
		}

		public IList<CategoryInfo> GetRecursiveParentsOfCategory(int categoryId, int baseCategoryId)
		{
			if (categoryId == baseCategoryId)
			{
				return new List<CategoryInfo>();
			}
			return dal.GetRecursiveParentsOfCategory(categoryId, baseCategoryId);
		}

		public IList<CategoryInfo> GetRecommandCategories(int pageIndex, int pageSize, out int totalRecords)
		{
			return dal.GerRecommandCategories(true, pageIndex, pageSize, out totalRecords);
		}

		public void RecommandCategory(int categoryId)
		{
			dal.SetCategoryRecommandState(categoryId, true);
		}

		public void UnrecommandCategory(int categoryId)
		{
			dal.SetCategoryRecommandState(categoryId, false);
		}

		public int GetCategoriesCount(int rootCategoryId)
		{
			return dal.GetCategoriesCount(rootCategoryId);
		}

		public DataSet GetExportDataSet(int categoryId)
		{
			return dal.GetExportDataSet(categoryId);
		}

		public IList<CategoryInfo> SearchCategories(string keywords, int pageIndex, int pageSize, out int totalRecords)
		{
			return dal.SearchCategories(keywords, pageIndex, pageSize, out totalRecords);
		}

		private void TydyCategoryList(IList<CategoryInfo> list)
		{
			for (int i = 0; i < list.Count - 1; i++)
			{
				for (int j = i + 1; j < list.Count; j++)
				{
					if (list[j].ParentCategoryId == list[i].ParentCategoryId)
					{
						CategoryInfo cat = list[j];
						if (list[j].Order > list[i].Order)
						{
							list.RemoveAt(j);
							list.Insert(i + 1, cat);
						}
						else
						{
							list.RemoveAt(j);
							list.Insert(i, cat);
						}
					}
					else if (list[j].ParentCategoryId == list[i].CategoryId)
					{
						CategoryInfo cat = list[j];
						list.RemoveAt(j);
						list.Insert(i + 1, cat);
					}
				}
			}

		}
	}
}
